import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.ScreenExtractor;
import ws.schild.jave.info.MultimediaInfo;

import java.io.File;
import java.util.*;

public class VideoUtil {
    private static final List<String> VIDEO_SUFFIX = Arrays.asList(".mp4", ".avi", ".m4v", ".flv", ".mov", ".mpg", ".mpeg", ".mkv", ".rmvb", ".3gp", ".wmv", ".wma", ".rm");


    /**
     * 视频截图
     *
     * @param sourcePath        视频文件路径
     * @param segmentStartTimes 每段的起始时间及对应的截图文件路径的Map
     * @throws EncoderException
     */
    public static void videoScreenshot(String sourcePath, Map<Long, String> segmentStartTimes) throws EncoderException {
        System.out.println("开始截图...");
        System.out.println("视频文件路径: " + sourcePath);

        // 获取截图文件路径列表
        Collection<String> targetPathList = segmentStartTimes.values();

        // 获取截取的秒数列表
        List<Long> secondsList = new ArrayList<>(segmentStartTimes.keySet());

        // 创建多媒体对象
        MultimediaObject multimediaObject = new MultimediaObject(new File(sourcePath));

        // 创建屏幕截图提取器
        ScreenExtractor screenExtractor = new ScreenExtractor();

        // 遍历秒数列表，进行截图
        for (int i = 0; i < secondsList.size(); i++) {
            String targetPath = targetPathList.toArray(new String[0])[i];
            File targetFile = new File(targetPath);
            System.out.println("截取截图: " + targetPath + " 在 " + secondsList.get(i) + " 秒");

            // 截取指定秒数的截图
            screenExtractor.renderOneImage(multimediaObject, -1, -1, secondsList.get(i) * 1000, targetFile, 1);
        }
        System.out.println("截图完成！");

    }

    /**
     * 视频截图
     *
     * @param sourcePath
     * @param targetPathList 截图文件路径列表
     * @param secondsList    截取的秒 列表 eg:[1,10,20] 截取 第1秒，第10秒，第20秒
     * @throws EncoderException
     */
    public static void videoScreenshot(String sourcePath, List<String> targetPathList, List<Long> secondsList) throws EncoderException {
        //默认截取第1秒
        if (secondsList == null || secondsList.isEmpty()) {
            secondsList = new ArrayList<>();
            secondsList.add(1L);
        }
        MultimediaObject multimediaObject = new MultimediaObject(new File(sourcePath));
        ScreenExtractor screenExtractor = new ScreenExtractor();
        for (int i = 0; i < secondsList.size(); i++) {
            String targetPath = targetPathList.get(i);
            File targetFile = new File(targetPath);
            screenExtractor.renderOneImage(multimediaObject, -1, -1, secondsList.get(i) * 1000, targetFile, 1);
        }
    }


    /**
     * 判断是否是视频
     *
     * @param suffix
     * @return
     */
    public static boolean isVideo(String suffix) {
        return suffix != null && VIDEO_SUFFIX.contains(suffix.toLowerCase());
    }

    /**
     * 获取资源时长
     *
     * @param localPath 预览地址
     * @param suffix
     * @return 时长 秒
     */
    private static Long getDuration(String localPath, String suffix) {
        if (isVideo(suffix)) {
            return 0L;
        }
        MultimediaInfo medisInfo = getVideoInfo(localPath);
        Long duration = medisInfo == null ? 0 : medisInfo.getDuration() / 1000;
        return duration;
    }


    /**
     * 获取视频信息
     *
     * @param sourcePath
     * @return
     */
    public static MultimediaInfo getVideoInfo(String sourcePath) {
        MultimediaInfo multimediaInfo = null;
        try {
            multimediaInfo = new MultimediaObject(new File(sourcePath)).getInfo();
        } catch (EncoderException e) {
            e.printStackTrace();
        }
        return multimediaInfo;
    }
    /**
     *  根据视频时长平分几段，获得是第几秒，得到截图位置的时间
     */


    /**
     * 根据视频时长平分几段，获得是第几秒，得到截图位置的时间
     *
     * @param localPath 预览地址
     * @param suffix    文件后缀
     * @param segments  要分成的段数
     * @return 每段的起始时间列表（秒）
     */
    public static List<Long> getSegmentStartTimes(String localPath, String suffix, int segments) {
        // 获取视频总时长（秒）
        Long totalDuration = getDuration(localPath, suffix);

        // 如果总时长为0，返回空列表
        if (totalDuration == 0L) {
            return Collections.emptyList();
        }

        // 计算每段的时长（秒）
        long segmentDuration = totalDuration / segments;

        // 初始化起始时间列表
        List<Long> segmentStartTimes = new ArrayList<>();

        // 计算每段的起始时间
        for (int i = 0; i < segments; i++) {
            long startTime = i * segmentDuration;
            segmentStartTimes.add(startTime);
        }

        return segmentStartTimes;
    }
    /**
     * 获取文件后缀名
     */

    /**
     * 获取文件后缀名
     *
     * @param filePath 文件路径
     * @return 文件后缀名（不包括点）
     */
    public static String getSuffix(String filePath) {
        if (filePath == null || filePath.isEmpty()) {
            return "";
        }

        // 查找最后一个点的位置
        int lastDotIndex = filePath.lastIndexOf('.');

        // 如果没有点或者点在最后一个位置，返回空字符串
        if (lastDotIndex == -1 || lastDotIndex == filePath.length() - 1) {
            return "";
        }

        // 返回点后面的部分作为后缀名
        return filePath.substring(lastDotIndex + 1);

        // String suffix = filePath.contains(".") ? filePath.substring(filePath.lastIndexOf(".")) : "";

    }


    /**
     * 根据视频时长平分几段，获得是第几秒，得到截图位置的时间
     *
     * @param localPath 预览地址
     * @param suffix    文件后缀
     * @param segments  要分成的段数
     * @param outputDir 截图文件保存的目录
     * @return 每段的起始时间及对应的截图文件路径的Map
     */
    public static Map<Long, String> getSegmentByNumber(String localPath, String suffix, int segments, String outputDir) {
        System.out.println("开始根据段数生成截图位置...");
        System.out.println("视频文件路径: " + localPath);
        System.out.println("输出目录: " + outputDir);

        // 获取视频总时长（秒）
        Long totalDuration = getDuration(localPath, suffix);

        // 如果总时长为0，返回空Map
        if (totalDuration == 0L) {
            return Collections.emptyMap();
        }

        // 计算每段的时长（秒）
        long segmentDuration = totalDuration / segments;

        // 初始化起始时间及对应截图文件路径的Map
        Map<Long, String> segmentStartTimes = new HashMap<>();

        // 获取文件名（不包括路径和后缀）
        String fileName = new File(localPath).getName();
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex != -1) {
            fileName = fileName.substring(0, lastDotIndex);
        }
        if (outputDir.isEmpty()) {
            outputDir = new File(localPath).getParent();
        }
        // 计算每段的起始时间及对应的截图文件路径
        for (int i = 0; i < segments; i++) {
            long startTime = i * segmentDuration;
            String screenshotPath = String.format("%s/%s-num-%d-%d.png", outputDir, fileName, startTime, i + 1);
            segmentStartTimes.put(startTime, screenshotPath);
            System.out.println("生成截图路径: " + screenshotPath + " 在 " + startTime + " 秒");

        }
        System.out.println("根据段数生成截图位置完成！");
        return segmentStartTimes;
    }


    /**
     * 根据视频时长和截图间隔，获得截图位置的时间
     *
     * @param localPath                 预览地址
     * @param suffix                    文件后缀
     * @param screenshotIntervalMinutes 截图间隔（分钟）
     * @return 每段的起始时间及对应的截图文件路径的Map
     */
    public static Map<Long, String> getSegmentByTimes(String localPath, String suffix, int screenshotIntervalMinutes, String outputDir) {
        System.out.println("开始根据时间间隔生成截图位置...");
        System.out.println("视频文件路径: " + localPath);
        System.out.println("输出目录: " + outputDir);

        // 获取视频总时长（秒）
        Long totalDuration = getDuration(localPath, suffix);

        // 如果总时长为0，返回空Map
        if (totalDuration == 0L) {
            return Collections.emptyMap();
        }

        // 计算每段的时长（秒）
        long screenshotIntervalSeconds = screenshotIntervalMinutes * 60L;

        // 计算需要截取的段数
        int segments = (int) (totalDuration / screenshotIntervalSeconds);

        // 初始化起始时间及对应截图文件路径的Map
        Map<Long, String> segmentStartTimes = new HashMap<>();

        // 获取文件名（不包括路径和后缀）
        String fileName = new File(localPath).getName();
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex != -1) {
            fileName = fileName.substring(0, lastDotIndex);
        }

        // 获取保存目录
        if (outputDir.length() == 0) {
            outputDir = new File(localPath).getParent();
        }

        // 计算每段的起始时间及对应的截图文件路径
        for (int i = 0; i < segments; i++) {
            long startTime = i * screenshotIntervalSeconds;
            String screenshotPath = String.format("%s/%s-time-%d-%d.png", outputDir, fileName, startTime, i + 1);
            segmentStartTimes.put(startTime, screenshotPath);
            System.out.println("生成截图路径: " + screenshotPath + " 在 " + startTime + " 秒");

        }
        System.out.println("根据时间间隔生成截图位置完成！");
        return segmentStartTimes;
    }
}